package com.block.datapush.form.item.util;


import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.codec.Base64Encoder;
import cn.hutool.core.util.StrUtil;
import com.block.common.enums.BaseTypeInfoEnum;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class YunMiaoDaoUtil {

    public static void main(String[] args) {

        String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA44I07bKCLhTLcqze/t4hq2avQAOZmp1XVpxgPR7hmg9WJ8tYNbov/7z5pe1Zp1AtTeSUaoxidJONBrkkFT4sbFs53RekU//1E1cjTlTVWOzSdhfIEt2pKQWwyza9tOL2+4GqO0dkh/nZsQU9mfTyZPvrFSk2sLrm3wdwdF7G74NXTRoSM+Puke9VscTa2jdQRex/u4luMflK3+VjZScxt09G/2/Cr4Ldhe7ifIIiYBBoY9zIBMglfYLkuYwNPItXY2ntWbXQDyQHBCZ8/nEO21VEDW4Qq4zFyLwZw75MRsh79NcomKTIW3Jy1nJ5ozxoKRvV0MAqk4hzMoSRx8KwNwIDAQAB";
//        String pubKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp/M0GL99aElX3bGBeEZxCRXy6J6nvpmqgj3CGe9dLM5Z0SWD2kItT/4iFVANdlW3pEcYxDFyTtUecxbeApCElDTccxMjuQ9ppaJ2pb4+bZXQwwvuX8Jr/jS8QtnIQIMIpMqJU3//wd/AJHTmCPAaJIF7gx/CpCGVVhWc5JzXH5/O2urA3M9/XB8KcEDLHqgU6HHJQzRDMD4gKODJzE0ruy5suX84/jDURowILhNeTqYOhHqVHhW3O8R2raHFpzDCGwSgVHtlG0gRv5Z/0QBRJr2ItoC2mnhJUnJ2CsndzrcYmNMKHs+tF3I6MJaouJ0YdEePrtLJrXkujhrZudJx8wIDAQAB";


        String priKey = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDjgjTtsoIuFMty\n" +
                "rN7+3iGrZq9AA5manVdWnGA9HuGaD1Yny1g1ui//vPml7VmnUC1N5JRqjGJ0k40G\n" +
                "uSQVPixsWzndF6RT//UTVyNOVNVY7NJ2F8gS3akpBbDLNr204vb7gao7R2SH+dmx\n" +
                "BT2Z9PJk++sVKTawuubfB3B0Xsbvg1dNGhIz4+6R71WxxNraN1BF7H+7iW4x+Urf\n" +
                "5WNlJzG3T0b/b8Kvgt2F7uJ8giJgEGhj3MgEyCV9guS5jA08i1djae1ZtdAPJAcE\n" +
                "Jnz+cQ7bVUQNbhCrjMXIvBnDvkxGyHv01yiYpMhbcnLWcnmjPGgpG9XQwCqTiHMy\n" +
                "hJHHwrA3AgMBAAECggEAVMT4ObTwooDnCVR2Rlq4CuhY1i5BNoX3u/LKPRvbjY63\n" +
                "WF6BAIveRJjCIFwesqPCLarEzip+qNctjdrAIhYncTxQhBvCA/Zz93/ZTN95Gwgq\n" +
                "pwvXZYgn9nwDUsSTzOlgg3fd2PaR88RZo4bDXDETfCMNhbX0hccuLN3VvdZuo2EF\n" +
                "yzL1hxcVVDd+GbaIkE3Ou8s1DvAHI6QdzDpHkZPp9L9RYb2hN3hoJX1woLOn0d/s\n" +
                "ZHh8TGarXeCfHSH5IENAhsH5VBWdiqw4AcjiH2Shde4rlLyrUtoxb/sbwhgUVBMF\n" +
                "lxcyAsQegLHa+oh/KL1G5WwYVjjrM0peADVkI2GkiQKBgQD8HgthMtnhBWvqGDSk\n" +
                "jqsyZ70z+u15WskKFgt2ntiIemJ8j7gXtAY8JBADSGs9bgL8EvpQoo8xFXu8UpXO\n" +
                "nYhH+k6PF6P8ulBdn6yUqkLNzx6GndK8Q8G2NcxtanA4hRkk+fZUtTqLs9pppExk\n" +
                "dmVdQH/gEil4dySXtL436BUEUwKBgQDnAyTd/9PGVJMUXQN/bkE4naiX2gKZ1egk\n" +
                "Wm4qa4DfQ4QsVP6ZxGY1vMShTnv4298qnw/6biyWIbmMKsY/b7de2wGj8+TKrein\n" +
                "PkkTYdqbTlPZAkfeasaPcOvsPpgpHuF8jVufGoavzGXwIsu03AcND5kUV8iNL3GB\n" +
                "CE0wIVmoDQKBgD0ujVRpIraYujd06FGGzcTNp/yVSEvK3D62WtHOen2kNYJE3kfi\n" +
                "SCEQH1KsoFmn+NFzSYuH53fh3sU0xWX+lLPi6m2PLxyFmjseJKNvLgcD3ESOyDUn\n" +
                "vDqbk6B51AHjStbOUhj8YdjFLJu2Y1N959tZa67UuXuibh7incaza2ZBAoGAXIk5\n" +
                "32N25V9De0i2+fikT5V3zzwZBp5U2xsOPhfKC6Tz8P4q7lVpy+TNrv/NUSZiAqSs\n" +
                "tdgkLA9eT/Nibk7F2U1JHu+3miiHpVah1w2/j66Uj70GJOYIm7TUDFIWiYJBOK83\n" +
                "IEhz4z+xJbwKdWwdtvGklC2FvGhgwxscMEdrrpECgYEApqABiocciQJW6U3LuYJ0\n" +
                "Y6Rb4JHMVhow5GmdZ8/B8nuyaHHV41YVvlpY6/dnTLa6+yeVqvDVc851PXJidxFa\n" +
                "luj6M9S/nW9cwRnXlEYycjT+q+7Trh2RPAQWrdkYQxQe9yXGFaL7tTva+8iNwPmK\n" +
                "k4GgkZ/MiZcl4AqIg0Y1SPY=";


        String content = "你好啊";

        String s = encryptByPublicKey(content, pubKey);

//        s ="P51jMGzdQJ8nFd6SKuHx0KHjtNj7THQ4mIKT6pyGsTnAq8HapmuDiV+KVFDMDqUnUwB9VAJE2n0YyZYtJg17EDWCBclXEpCXGIx5cleby0noYzcTQMHpqcgVT0DuuxYtZx16yQxWesPpAfP2xBy21nhc/1koG3kt1EF4ZCPIUUeSaRiLDF6e8J0nQBiqCYL0sqzyM5EPK93ndoE8T6I/aZ0Nj2Z857/gTGcOtjPfgou+auEeLjBkhHcovKqRvyfE3zddYe2+y5LHeOo2f83Obi9VNvuSrw0uZ2bUeFRvwL4/n+JexjDqtJPyvSNtwhz6pdCdpl5Et7mBbXehbfnGWw5QYD8VdgRitiWg+0ObWkOBFsYlDYDZYVn+DfCCmvtREh1d8DGllP95DCoQQSDR3aGbxkj70GsCelXbUe2XRXINNwFKGv31Xzm8hmxEhyHKrfqI2xxcXGBSJz2knmNZ5jDwp2wzNBgCAgwqZUVyLIavV7zzjCkTZHTUCcyW9We9JHYDbg22wOXkVvNnxSQlAPcmhbtrHP7ql0hLL5mL6n3vQm8XL2uJaL6HeL4b/hshaciKrZb0HnV2VSswwwbE/jfxRqLDjW3d6UyfImStMxLH9Cce3WqGYaDsWGFHNMiRoSDHxpiYi2WVmA2Bj1+HUc+zrGzU3a/57Bzq7UV8c3pXXKR8PmlVJqG901euOd57QEjNRmPQCSzi0/OvH4UOugYFqX69l9xSygxFI1RtMC8860H5SSgpdDOoBWRNtyjs48NX2EnUAWr7gWVInXCR8s60u4Q/5zIfIUh4zf42dtXau6lJxNboRd+YvDQRSO6Xwd8BeobnP7bkq63Or3ZCIBvkNik1H2+hUpC0j/XQfi7bw6xJfEFTqe0zPB+HJErwVHPS8tA78PMiWyj6aubP3dIdSfjZEcbG6rqQf/jQMw7q/Ev7lzYohSNTzHe04HxXfrqIsDHbXpbtK7IN4+QttPNyJc4aJRhjI98eoXF7oavPbyE7/AKxC7aEWjkkfQpN";

        s = "maSUjgZpmF8geUrTMLKghzbA9Nnav71sZs/3oYp1LuwxeGrL2IBo3eYWKf4Xi4QjZndAzhkEbKyFShBQOmpnsgXkamSInkw5W/JJ4kwDjtK7zX/tA0KY2G06ZRRsOOgEcqRz5pDMi1A6ATLk8fVlFGJGjgGjHjcsr4v1BsYNADio6AtfOvHJp3MaEUvXv6IBGPsug1RXMkSy7S8bPMkbzF5R+rGXa+30E+dxOpLXOCq8nmO9AML9q3R5+z7M/+qW7Q7FJIOAj7eJalkKFiTRNRHUUuJEmfW4+XyXTWFS5fhkxQA6j4DH/0VXtzsRGmsFBUeQQ5Ce2XHw3kRcgGGn5EY+sg6RvsDuzkPs8WxMgjxAMTBMe2Og/I0rp6JJJYUe/6/Z2EDeW7A45qZsosWSk5jYiVrr4I9Ov1/qNz5VsrtIYqlTmbXMaW50A8sQW6izYfkMhcxTDX2UaZSLAnZ5lL02XCx8+FZDvoweTG1/HXH5OJ3sPb4l43jd3Dy8CV0LZJDeHE8s++Pe27wsb42ZKQoHVL8BS8msi740hGZpTZFLQr4OqB+C6rHZqy08Xqc8eEOnHPm2rVVE7dtSEIb+mQt2t9bAuxuQPtp4MrbWfdlisHO3r3EAFk5nR0OxQj2wzAPVL+kTfCOeFZcarciAIXCboMLKYBfu2RC/pE5qlhFmBpaykD45/aRr3UNW3MQwYMBB6r2bEbjnM6AbInxvUrsuuV3Dpjaorhj/uK1kwbcFWYHUGImldZQMCzrty6Oj2dkA5+NFkR0KLB69/CWOBRa8nRg1t+eFsBmTp8vgNezqdKaPFIz3ayFRq+QGZbyR5sPPcg83F5SHJxmcYBLu8CMNW7qugAgHbSyraqiWJGUcnsG8DgcjoLfqkCDBt2lmYasBe08XXeI08dIV9EVSziLyh8bcgU1OBUaU2np4GIshNRXxzy8pSOffa/eFQuOmoFpomO0jKMbO8cEUlBWAOVO8CgO/Rwiann9LvIFY22mArU7kG33e8NGEBtWI8Rih";

        String s1 = decryptByPrivateKey(s, priKey);



        System.out.println(s);

        System.out.println();
        System.out.println();

        System.out.println(s1);

    }


    /**
     * 使用公钥加密
     *
     * @see
     */
    public static String encryptByPublicKey(String data, String publicKey) {
        // 加密
        String str = "";
        int outNum = 2048 / 8 - 11;
        try {
            byte[] pubbyte = base64decode(publicKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.ENCRYPT_MODE, rsaPubKey);
            byte[] dataBytes = data.getBytes();
            int inputLen = data.getBytes().length;
            int offSet = 0;
            byte[] cache;
            byte[] bigByte = new byte[0];
            int i = 0;
            if (inputLen > outNum) {
                while (inputLen - offSet > 0) {
                    if (inputLen - offSet >= outNum) {
                        cache = subBytes(dataBytes, offSet, outNum);
                        bigByte = byteMerger(bigByte, c1.doFinal(cache));
                    } else {
                        cache = subBytes(dataBytes, offSet, inputLen - offSet);
                        bigByte = byteMerger(bigByte, c1.doFinal(cache));
                    }
                    i++;
                    offSet = i * outNum;
                }
                str = base64encode(bigByte);
            } else {
                str = base64encode(c1.doFinal(dataBytes));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }

    /**
     * 截取byte数组
     *
     * @param src
     * @param begin
     * @param count
     * @return
     */
    public static byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    /**
     * 合并byte[]数组 （不改变原数组）
     *
     * @param byte_1
     * @param byte_2
     * @return 合并后的数组
     */
    public static byte[] byteMerger(byte[] byte_1, byte[] byte_2) {
        byte[] byte_3 = new byte[byte_1.length + byte_2.length];
        System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
        System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
        return byte_3;
    }

    /**
     * base64解密
     *
     * @param str
     * @return byte[]
     */
    @SuppressWarnings("restriction")
    private static byte[] base64decode(String str) {
        byte[] bt = null;
        try {
            bt = Base64Decoder.decode(str);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return bt;
    }

    /**
     * base64加密
     *
     * @param bstr
     * @return
     */
    @SuppressWarnings("restriction")
    private static String base64encode(byte[] bstr) {
        String str = Base64Encoder.encode(bstr);
        str = str.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");
        return str;
    }

    /**
     * 本方法使用SHA1withRSA签名算法产生签名
     *
     * @param src 签名的原字符串
     * @return String 签名的返回结果(16进制编码)。当产生签名出错的时候，返回null。
     */
    public static String signByPrivateKey(String src, String priKey) {
        try {
            Signature sigEng = Signature.getInstance("SHA1withRSA");
            byte[] pribyte = base64decode(priKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
            sigEng.initSign(privateKey);
            sigEng.update(src.getBytes());
            byte[] signature = sigEng.sign();
            return base64encode(signature);
        } catch (Exception e) {
            System.out.println("=====签名生成失败");
            return null;
        }
    }

    /**
     * 使用私钥解密
     *
     * @see
     */
    public static String decryptByPrivateKey(String data, String priKey) {
        try {
            int outNum = 2048 / 8;
            byte[] pribyte = base64decode(priKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pribyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPrivateKey privateKey = (RSAPrivateKey) fac.generatePrivate(keySpec);
            Cipher c1 = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            c1.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] bytes = base64decode(data);
            int inputLen = bytes.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > outNum) {
                    cache = c1.doFinal(bytes, offSet, outNum);
                } else {
                    cache = c1.doFinal(bytes, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * outNum;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            String res = new String(decryptedData, "utf-8");
            return unicodeToString(res);
        } catch (Exception e) {
            System.out.println("=====解密失败"+e);
            return null;
        }

    }

    /**
     * unicode转字符串
     *
     * @param str
     * @return
     */
    public static String unicodeToString(String str) {
        Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
        Matcher matcher = pattern.matcher(str);
        char ch;
        while (matcher.find()) {
            //group 6728
            String group = matcher.group(2);
            //ch:'木' 26408
            ch = (char) Integer.parseInt(group, 16);
            //group1 \u6728
            String group1 = matcher.group(1);
            str = str.replace(group1, ch + "");
        }
        return str;
    }

    /**
     * 使用公钥验证签名
     *
     * @param sign
     * @param src
     * @return
     */
    public static boolean verifyByPublicKey(String sign, String src, String pubKey) {
        try {
            Signature sigEng = Signature.getInstance("SHA1withRSA");
            byte[] pubbyte = base64decode(pubKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubbyte);
            KeyFactory fac = KeyFactory.getInstance("RSA");
            RSAPublicKey rsaPubKey = (RSAPublicKey) fac.generatePublic(keySpec);
            sigEng.initVerify(rsaPubKey);
            sigEng.update(src.getBytes());
            byte[] sign1 = base64decode(sign);
            return sigEng.verify(sign1);
        } catch (Exception e) {
            System.out.println("=====验签失败");
            return false;
        }
    }

    /**
     * ["3000-5000", "5000-1万", "1万以上", "-"]
     * @param loanAmount
     * @return
     */
    public static Integer getLoanAmount(String loanAmount) {
        if (StrUtil.equals(BaseTypeInfoEnum.LoanAmount.la001.getValue(), loanAmount)){
            return 3;
        }else if (StrUtil.equals(BaseTypeInfoEnum.LoanAmount.la002.getValue(), loanAmount)){
            return 5;
        }else if (StrUtil.equals(BaseTypeInfoEnum.LoanAmount.la003.getValue(), loanAmount)){
            return 10;
        }
        return 3;
    }

    /**
     * ["无社保", "未满6个月", "6个月以上", "-"]
     * @param shebao
     * @return
     */
    public static String getShebao(String shebao) {
        if (StrUtil.equals(BaseTypeInfoEnum.SocialInsurance.si001.getValue(), shebao)){
            return "无社保";
        }else if (StrUtil.equals(BaseTypeInfoEnum.SocialInsurance.si002.getValue(), shebao)){
            return "6个月以上";
        }
        return "-";
    }

    /**
     * ["无公积金", "未满6个月", "6个月以上", "-"]
     * @param gjj
     * @return
     */
    public static String getGjj(String gjj) {
        if (StrUtil.equals(BaseTypeInfoEnum.Gjj.gjj001.getValue(), gjj)){
            return "无公积金";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Gjj.gjj002.getValue(), gjj)){
            return "6个月以上";
        }
        return "-";
    }

    /**
     * ["无房产", "有房不抵押", "有房可抵押", "-"]
     * @param house
     * @return
     */
    public static String getHouse(String house) {
        if (StrUtil.equals(BaseTypeInfoEnum.House.hu001.getValue(), house)){
            return "无房产";
        }else if (StrUtil.equals(BaseTypeInfoEnum.House.hu002.getValue(), house)){
            return "有房可抵押";
        }
        return "-";
    }

    /**
     * ["无车辆", "有车不抵押", "有车可抵押", "-"]
     * @param car
     * @return
     */
    public static String getCar(String car) {
        if (StrUtil.equals(BaseTypeInfoEnum.Car.car001.getValue(), car)){
            return "无车辆";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Car.car002.getValue(), car)){
            return "有车可抵押";
        }
        return "-";
    }

    /**
     * ["无保单", "未满1年", "1年以上", "-"]
     * @param baodan
     * @return
     */
    public static String getBaodan(String baodan) {
        if (StrUtil.equals(BaseTypeInfoEnum.Insurance.in001.getValue(), baodan)){
            return "无保单";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Insurance.in002.getValue(), baodan)){
            return "1年以上";
        }
        return "-";
    }

    public static String getBaitiao(String baitiao) {
        if (StrUtil.equals(BaseTypeInfoEnum.Baitiao.bt001.getValue(), baitiao)){
            return "无";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Baitiao.bt002.getValue(), baitiao)){
            return "5000以上";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Baitiao.bt003.getValue(), baitiao)){
            return "5000以上";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Baitiao.bt004.getValue(), baitiao)){
            return "5000以上";
        }
        return "-";
    }

    /**
     * ["600分以下", "600-650分", "650-700分",
     * "700分以上", "-"]
     * @param zhima
     * @return
     */
    public static String getZhima(String zhima) {
        if (StrUtil.equals(BaseTypeInfoEnum.ZhimaScore.zm001.getValue(), zhima)){
            return "600分以下";
        }else if (StrUtil.equals(BaseTypeInfoEnum.ZhimaScore.zm002.getValue(), zhima)){
            return "600分以下";
        }else if (StrUtil.equals(BaseTypeInfoEnum.ZhimaScore.zm003.getValue(), zhima)){
            return "600-650分";
        }else if (StrUtil.equals(BaseTypeInfoEnum.ZhimaScore.zm004.getValue(), zhima)){
            return "650-700分";
        }else if (StrUtil.equals(BaseTypeInfoEnum.ZhimaScore.zm005.getValue(), zhima)){
            return "700分以上";
        }
        return "600分以下";
    }

    public static String getHuabei(String huabei) {
        if (StrUtil.equals(BaseTypeInfoEnum.Huabei.hb001.getValue(), huabei)){
            return "无";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Huabei.hb002.getValue(), huabei)){
            return "5000以上";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Huabei.hb003.getValue(), huabei)){
            return "5000以上";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Huabei.hb004.getValue(), huabei)){
            return "5000以上";
        }
        return "-";
    }

    public static String getYuqi(String yuqi) {
        if (StrUtil.equals(BaseTypeInfoEnum.Yuqi.yq001.getValue(), yuqi)){
            return "有";
        }else if (StrUtil.equals(BaseTypeInfoEnum.Yuqi.yq001.getValue(), yuqi)){
            return "无";
        }
        return "-";
    }

    public static String getCity(String city, String province) {
        if (cityList.contains(province))return province;
        return city;
    }

    public static String getProvince(String province) {
        return province;
    }

    public static List<String> cityList = Arrays.asList("北京市", "天津市","上海市","重庆市");


//    /**
//     * JSON字符串排序 升序
//     * @param
//     * @return
//     */
//    public static String sortString(String str) {
//        com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(str);
//        return com.alibaba.fastjson.JSONObject.toJSONString(jsonObject, SerializerFeature.SortField.MapSortField);
//    }
}